home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- *
- * Apple Developer Technical Support
- *
- * I/O handling routines
- *
- * Program: EditionSample
- * File: Files.c - C Source
- *
- * by: C.K. Haun <TR>
- *
- * Copyright © 1990,1991 Apple Computer, Inc.
- * All rights reserved.
- *
- *------------------------------------------------------------------------------
- * This file handles saving and loadingg the documents created by this sample.
- * All the standard data load/save is taken care of in this file, while the
- * Edition Manager specific routines are in their own files (Publish.c or
- * Subscribe.c) and are called from here.
- *----------------------------------------------------------------------------*/
-
- /* File handling here */
- #define __FILES__
-
- #pragma segment Files
- #pragma load "EdSampheaders" /* see the Buildheaders.c file */
-
- #include "EdSampdefines.h"
- void ReadDocData(windowCHandle newWinControl, short readRefNum);
-
- extern void HandleSectionSave(windowCHandle theWind, Boolean writeEm, Boolean dereg, FSSpec *theSpec);
- extern void WritePublishers(windowCHandle theWind);
- extern WindowPtr AddNewWindow(Boolean showIt);
- extern void StorePublisher(windowCHandle shortName, SectionHandle storeSection, Rect *inRect, textSectionHandle textIn,
- OSType typeIn);
- extern void StoreSubscriber(windowCHandle shortName, SectionHandle secHandle, Handle inRect, Handle pictIn);
- extern OSErr MyReadSection(SectionHandle theSection);
- extern short actsToIDs[];
- SFTypeList myList =
- {
- 'Fred'
- };
-
-
-
-
- /* SaveMe saves the passes window data, and all the associated sections.
- * It does NOT perform a 'safe' save, it kills the old data and recreates it.
- * Future versions of this sample will do a 'safe' save.
- */
- /* windowCHandle is locked on entry to this mess */
- void SaveMe(windowCHandle theWind, WindowPtr theWindPtr)
- {
- Boolean myWasChanged;
- register qq;
- StandardFileReply saveReply;
- short saveRefNum;
- FSSpec saveFileSpec;
- OSErr myErr;
- Str255 wName;
- Handle nameStr;
- extern PicHandle MyMakePicture(Rect * thisRect);
- long toWrite;
- extern WindowPtr gCurrentWindow;
- /* if the filealias handle is 0 size, then this file has not been saved yet, so we */
- /* need to call Standard File. I'm using the new StandardGetFile call, this */
- /* call is better in (at least) two ways. First, you no longer pass a Point as */
- /* a parameter, instead, the dialog is centered on the main screen for you. Secondly, */
- /* StandardGetFile returns a FSSpec record in the reply record. This means that you */
- /* can use the new FSp type calls, as well as using the FSSpec to generate an Alias */
- /* easily. */
- if (GetHandleSize((Handle)(*theWind)->fileAliasHandle) == 0) {
- StandardPutFile("\pSave document as....", wName, &saveReply);
- if (!saveReply.sfGood)
- return;
- saveFileSpec = saveReply.sfFile;
- if (saveReply.sfReplacing)
- FSpDelete(&saveFileSpec);
- /* change the name of the window to this filename */
- SetWTitle(theWindPtr, saveFileSpec.name);
- } else {
- /* Resolve the old alias that was kept with the window */
- /* in this case I don't care if the alias needed to be updated or not, this ain't */
- /* a real time critical routine */
- myErr = ResolveAlias(nil, ((*theWind)->fileAliasHandle), &saveFileSpec, &myWasChanged);
- if (myErr) {
- ShowMe("\pResolving Alias ", myErr);
- return;
- }
- /* kill current file, ignoring errors */
- FSpDelete(&saveFileSpec);
- }
- SetCursor(*GetCursor(watchCursor));
- myErr = FSpCreate(&saveFileSpec, 'CKH6', 'Fred', 1);
- if (myErr) {
- ShowMe("\pCreating file ", myErr);
- SetMyCursor(actsToIDs[(*theWind)->currentAction]);
- return;
- }
-
- /* replace the nil handle with the alias record please, in our window data struct */
- DisposeHandle((Handle)(*theWind)->fileAliasHandle);
- if (myErr = NewAlias(nil, &saveFileSpec, &((*theWind)->fileAliasHandle))) {
- ShowMe("\pDuring New Alias ", myErr);
- SetMyCursor(actsToIDs[(*theWind)->currentAction]);
- return;
- }
- /* First save the drawing commands that make up this window */
-
- myErr = FSpOpenDF(&saveFileSpec, fsRdWrPerm, &saveRefNum);
- if (myErr) {
- ShowMe("\pOpening file ", myErr);
- SetMyCursor(actsToIDs[(*theWind)->currentAction]);
- return;
- }
- /* save off lines, rects, ovals. If there is a selection currently, it's lost */
- /* lines */
- toWrite = sizeof(short);
- myErr = FSWrite(saveRefNum, &toWrite, (Ptr)&(*theWind)->lineCount);
- if (myErr) {
- ShowMe("\pWriting file ", myErr);
- }
- if ((*theWind)->lineCount != 0) {
- HLock((Handle)(*theWind)->lineList);
- toWrite = GetHandleSize((Handle)(*theWind)->lineList);
- FSWrite(saveRefNum, &toWrite, *((Handle)(*theWind)->lineList));
- HUnlock((Handle)(*theWind)->lineList);
- }
- /* rectangles, count, then a copy of the handle */
- toWrite = sizeof(short);
- FSWrite(saveRefNum, &toWrite, (Ptr)&(*theWind)->rectCount);
- if ((*theWind)->rectCount != 0) {
- HLock((Handle)(*theWind)->rectList);
- toWrite = GetHandleSize((*theWind)->rectList);
- FSWrite(saveRefNum, &toWrite, *((*theWind)->rectList));
- HUnlock((Handle)(*theWind)->rectList);
- }
- /* and ovals */
- toWrite = sizeof(short);
- FSWrite(saveRefNum, &toWrite, (Ptr)&(*theWind)->ovalCount);
- if ((*theWind)->ovalCount != 0) {
- HLock((Handle)(*theWind)->ovalList);
- toWrite = GetHandleSize((*theWind)->ovalList);
- FSWrite(saveRefNum, &toWrite, *((*theWind)->ovalList));
- HUnlock((Handle)(*theWind)->ovalList);
- }
- /* and pictures, I'm putting them in the data fork just because, OK? */
- /* Actually, I'm doing it to prevent any conflict with resource for */
- /* subscribers. I could check for unique IDs and all that, but sometimes */
- /* simplicity works well.... */
-
- toWrite = sizeof(short);
- FSWrite(saveRefNum, &toWrite, (Ptr)&(*theWind)->numPicts);
- if ((*theWind)->numPicts != 0) {
- Handle * thePict;
- Handle *thePictRect;
-
- HLock((Handle)(*theWind)->pictHandle);
- HLock((Handle)(*theWind)->pictRects);
- thePict = (Handle *)*(*theWind)->pictHandle;
- thePictRect = (Handle *)*(*theWind)->pictRects;
- for (qq = 0; qq < (*theWind)->numPicts; qq++) {
- short writeSize;
- toWrite = sizeof(short);
- writeSize = GetHandleSize((Handle)*thePict);
- FSWrite(saveRefNum, &toWrite, (Ptr)&writeSize);
- toWrite = writeSize;
- HLock((Handle)*thePict);
- FSWrite(saveRefNum, &toWrite, (Ptr)(*(*thePict)));
- HUnlock((Handle)*thePict);
- /* and the rect */
- toWrite = sizeof(Rect);
- HLock((Handle)*thePictRect);
- FSWrite(saveRefNum, &toWrite, (Ptr)(*(*thePictRect)));
- HUnlock((Handle)*thePictRect);
- thePictRect += 1;
- thePict += 1;
- }
- HUnlock((Handle)(*theWind)->pictHandle);
- HUnlock((Handle)(*theWind)->pictRects);
- }
- toWrite = sizeof(short);
- if ((*theWind)->boxHandle != nil) {
- CharsHandle theText;
- short textLen;
- /* save the text and the rectangle */
- theText = TEGetText((*theWind)->boxHandle);
- HLock((Handle)theText);
- textLen = GetHandleSize((Handle)theText);
- /* have to write it out the length of the text now */
- toWrite = sizeof(short);
- FSWrite(saveRefNum, &toWrite, (Ptr)&textLen);
- /* and the text itself */
- toWrite = textLen;
- FSWrite(saveRefNum, &toWrite, (Ptr)*theText);
- /* and save out the rectangle */
- toWrite = sizeof(Rect);
- FSWrite(saveRefNum, &toWrite, (Ptr)&(*theWind)->textBox);
- } else {
- short nothing = 0;
- FSWrite(saveRefNum, &toWrite, (Ptr)¬hing); /* a pointer to nothing. Leads to the 'No Exit' sign in Sartè */
- }
- FSClose(saveRefNum);
- /* this takes care of the data fork of the file. Now we need to save
- * publisher and subcriber data in the resource fork */
- HCreateResFile(saveFileSpec.vRefNum, saveFileSpec.parID, saveFileSpec.name);
- if (myErr = ResError()) {
- ShowMe("\pCreating Rez fork", myErr);
- SetMyCursor(actsToIDs[(*theWind)->currentAction]);
- return;
- }
- saveRefNum = HOpenResFile(saveFileSpec.vRefNum, saveFileSpec.parID, saveFileSpec.name, fsRdWrPerm);
- if (myErr = ResError()) {
- ShowMe("\pHOpening resource fork ", myErr);
- SetMyCursor(actsToIDs[(*theWind)->currentAction]);
- return;
- }
- /* add our 'name' string to this file (see 'The Finder Interface' chapter of IM VI) */
- nameStr = GetResource('STR ', 1000);
- DetachResource(nameStr);
- UseResFile(saveRefNum);
- AddResource(nameStr, 'STR ', -16396, "");
- /* HandleSectionSave saves off the 'sect' and 'alis' resources for all our */
- /* publishers and subscribers */
- HandleSectionSave(theWind, true, false, &saveFileSpec);
- CloseResFile(saveRefNum);
- FlushVol("", saveFileSpec.vRefNum);
- (*theWind)->windowDirty = false;
- SetMyCursor(actsToIDs[(*theWind)->currentAction]);
- }
-
- /* end SaveMe */
-
- /* OpenFile reads in our drawing commands, and all the publisher and */
- /* subscriber data, and registers all our sections */
- WindowPtr OpenFile(FSSpec *inSpec)
- {
- long numSections;
- register qq;
- long counter = 0;
- OSErr myErr;
- WindowPtr newWindow;
- windowCHandle newWinControl;
- Handle textFromFile;
- FSSpec readFileSpec;
- long toRead;
- short readRefNum;
- StandardFileReply openReply;
- SFTypeList myList = {
- 'Fred'
- };
-
- if (inSpec) { /* if it was called by an ODOC AppleEvent then our AppleEvent handler */
- /* will pass the FSSpec that the AE contained */
- readFileSpec = openReply.sfFile = *inSpec;
- } else {
- StandardGetFile((FileFilterProcPtr)0, 1, myList, &openReply);
- if (!openReply.sfGood)
- return; /* scat if they canceled */
- readFileSpec = openReply.sfFile;
- }
- if ((openReply.sfType != 'Fred') && (inSpec == nil)) {
- ShowMe("\pfilter not working", 0);
- return;
- }
- SetCursor(*GetCursor(watchCursor));
- newWindow = AddNewWindow(false); /* ask for a new window */
- if (newWindow == nil) {
- InitCursor();
- return(nil);
- } /* bail if it failed */
- newWinControl = (windowCHandle)GetWRefCon(newWindow);
- HLock((Handle)newWinControl);
- /* window opened, set title to file name, and create an alias to store in the */
- /* struct. */
- SetWTitle(newWindow, readFileSpec.name);
- DisposeHandle((Handle)(*newWinControl)->fileAliasHandle); /* kill the null handle */
- if (myErr = NewAlias(nil, &readFileSpec, &((*newWinControl)->fileAliasHandle))) {
- ShowMe("\pDuring New Alias ", myErr);
- return;
- }
- /* now open the data fork of the file and read in our drawing commands */
- if (myErr = FSpOpenDF(&openReply.sfFile, fsRdPerm, &readRefNum)) {
- ShowMe("\pOpening file ", myErr);
- return;
- }
- ReadDocData(newWinControl, readRefNum);
- readRefNum = HOpenResFile(readFileSpec.vRefNum, readFileSpec.parID, readFileSpec.name, fsRdWrPerm);
- UseResFile(readRefNum);
- /* now load in the sections and aliases */
- /* Load each section, and store it in the appropriate area (pub or sub) */
- /* Then register the sections. */
- /* ••• NOTE: As soon as you register a section, the Edition Manager may generate an */
- /* event for that section. All the subscribers may get a Section Read event, for */
- /* example, and some of the publishers will probably get a section write. */
- /* So, don't assume anything. Don't write sections or read sections yourself, wait for */
- /* the Edition Manager to generate the right events, this will insure that you are always */
- /* current and NOT fighting with the EM */
- /* how many sections are there? */
- numSections = Count1Resources(rSectionType);
- /* loop through them all */
- if (numSections) {
- for (counter = 0; counter < numSections; counter++) {
- SectionHandle inSection;
- AliasHandle inAlias;
- Handle auxDataIn;
- short inID;
- ResType tempRT;
- Str255 tempRName;
- Boolean aliasUpdated;
- FSSpec tempSpec;
- inSection = (SectionHandle)Get1IndResource(rSectionType, counter + 1);
- /* this GetResInfo call is here to give us the ResID of the section. Since the alias */
- /* for this section was stored with the same ID, we can get it easily. */
- GetResInfo((Handle)inSection, &inID, &tempRT, &tempRName);
- inAlias = (AliasHandle)Get1Resource(rAliasType, inID);
- myErr = ResError();
- if ((myErr != 0) || (inAlias == nil))
- ShowMe("\palias error", myErr);
- DetachResource((Handle)inSection);
- DetachResource((Handle)inAlias);
- /* depending on our type depends on what else we bring in */
- /* text data or picture stuff */
- switch ((*inSection)->refCon & 0xf) {
- case kPictType:
- auxDataIn = Get1Resource('RECT', inID);
- DetachResource(auxDataIn);
- break;
- case kTextType:
- /* I do need */
- /* to get my textSection record back so I have my start-end offsets */
- auxDataIn = Get1Resource(rMyTextRecordType, inID);
- DetachResource(auxDataIn);
- break;
-
- }
- /* Put the alias in the section, since the old handle stored there means nothing now */
-
- (*inSection)->alias = inAlias;
- /* now we have to determine if this was a pub or sub, since we have to load the */
- /* publish rectangle resource if it was a publisher */
- /* Now tell the Edition Manager that this section is back on line and ready to */
- /* receive events */
- if (myErr = RegisterSection(&readFileSpec, inSection, &aliasUpdated)) {
- ShowMe("\pRegistering Section ", myErr);
- /* return; */
- inSection = nil;
- }
- if (inSection) {
-
- if ((*inSection)->kind == stPublisher) {
-
- /* get the rectangle */
- switch ((*inSection)->refCon & 0xf) {
- case kPictType:
- HLock(auxDataIn);
- StorePublisher(newWinControl, inSection, (Rect *)*auxDataIn, nil, 'PICT'); /* in Publish.c */
- DisposeHandle(auxDataIn);
- /* mark all incoming sections as having been saved once, so we don't */
- /* delete them accidentalllly when this window closes */
- (*inSection)->refCon |= kSavedOnce;
-
- break;
- case kTextType:
- /* need to get the text contained in this thing */
- textFromFile = Get1Resource(rMyTextBlock, inID);
- DetachResource(textFromFile);
- (*(textSectionHandle)auxDataIn)->theText = textFromFile;
- /* associate the section with the text section */
- (*(textSectionHandle)auxDataIn)->theSection = inSection;
- /* and store it away */
-
- StorePublisher(newWinControl, inSection, nil, (textSectionHandle)auxDataIn, 'TEXT');
- /* mark all incoming sections as having been saved once, so we don't */
- /* delete them accidentalllly when this window closes */
- (*inSection)->refCon |= kSavedOnce;
- break;
-
- }
- } else {
- Handle picIn;
- switch ((*inSection)->refCon & 0xf) {
- case kPictType:
- picIn = (Handle)GetPicture(inID);
- DetachResource((Handle)picIn);
- if (ResError())
- ShowMe("\ppicture get", 0);
- /* need to get the picture here */
- StoreSubscriber(newWinControl, inSection, auxDataIn, picIn); /* in Subscribe.c */
- break;
- case kTextType:
- /* need to get the text contained in this thing */
- textFromFile = Get1Resource(rMyTextBlock, inID);
- DetachResource(textFromFile);
- (*(textSectionHandle)auxDataIn)->theText = textFromFile;
- /* associate the section with the text section */
- (*(textSectionHandle)auxDataIn)->theSection = inSection;
- (*(textSectionHandle)auxDataIn)->nextSection = nil;
- /* and store it away */
- /* I'll be using the auxDataIn field for the textSectionHandle */
- StoreSubscriber(newWinControl, inSection, auxDataIn, nil); /* in Subscribe.c */
-
- break;
- }
- }
- }
- }
- }
- CloseResFile(readRefNum);
- HUnlock((Handle)newWinControl);
- ShowWindow(newWindow);
- ChangePlane(newWindow);
- InitCursor();
- return(newWindow);
- }
-
- /* Reads the actual document data out of the file. This is not in the OpenFile function */
- /* for secret reasons that will become apparent in a future release of this sample..... */
- /* the window control structure in this window ptr is locked on entry */
- /* I'm passing the window instaed of the window control handle because I may */
- /* have to create a text edit record */
- void ReadDocData(windowCHandle newWinControl, short readRefNum)
- {
- long toRead;
- register qq;
- short aShort;
- /* read in lines, rects, ovals. */
-
- GetEOF(readRefNum, &toRead);
- if (toRead) { /* Make sure that there is some data to read */
- /* lines */
- toRead = sizeof(short);
- FSRead(readRefNum, &toRead, (Ptr)&(*newWinControl)->lineCount);
- if ((*newWinControl)->lineCount != 0) {
- HUnlock((Handle)(*newWinControl)->lineList);
- MySetHandleSize((Handle)(*newWinControl)->lineList, ((*newWinControl)->lineCount) * sizeof(myLine));
- HLock((Handle)(*newWinControl)->lineList);
- toRead = ((*newWinControl)->lineCount) * sizeof(myLine);
- FSRead(readRefNum, &toRead, *((Handle)(*newWinControl)->lineList));
- HUnlock((Handle)(*newWinControl)->lineList);
- }
-
- /* rectangles, count, then a copy of the handle */
- toRead = sizeof(short);
- FSRead(readRefNum, &toRead, (Ptr)&(*newWinControl)->rectCount);
- if ((*newWinControl)->rectCount != 0) {
- HUnlock((Handle)(*newWinControl)->rectList);
- MySetHandleSize((Handle)(*newWinControl)->rectList, ((*newWinControl)->rectCount) * sizeof(Rect));
- HLock((Handle)(*newWinControl)->rectList);
- toRead = GetHandleSize((*newWinControl)->rectList);
- FSRead(readRefNum, &toRead, *((*newWinControl)->rectList));
- HUnlock((Handle)(*newWinControl)->rectList);
- }
- /* and ovals */
- toRead = sizeof(short);
- FSRead(readRefNum, &toRead, (Ptr)&(*newWinControl)->ovalCount);
- if ((*newWinControl)->ovalCount != 0) {
- HUnlock((Handle)(*newWinControl)->ovalList);
- MySetHandleSize((Handle)(*newWinControl)->ovalList, ((*newWinControl)->ovalCount) * sizeof(Rect));
- HLock((Handle)(*newWinControl)->ovalList);
- toRead = GetHandleSize((*newWinControl)->ovalList);
- FSRead(readRefNum, &toRead, *((*newWinControl)->ovalList));
- HUnlock((Handle)(*newWinControl)->ovalList);
- }
- toRead = sizeof(short);
- FSRead(readRefNum, &toRead, (Ptr)&(*newWinControl)->numPicts);
- if ((*newWinControl)->numPicts != 0) {
- Handle * tempPictHand;
- Handle *tempPictRects;
- HUnlock((*newWinControl)->pictHandle);
- HUnlock((*newWinControl)->pictRects);
- MySetHandleSize((*newWinControl)->pictHandle, (sizeof(Handle) * ((*newWinControl)->numPicts)));
- MySetHandleSize((*newWinControl)->pictRects, (sizeof(Handle) * ((*newWinControl)->numPicts)));
- HLock((*newWinControl)->pictHandle);
- HLock((*newWinControl)->pictRects);
- tempPictRects = (Handle *)*((*newWinControl)->pictRects);
- tempPictHand = (Handle *)*((*newWinControl)->pictHandle);
- /* read in picts please */
- for (qq = 0; qq < (*newWinControl)->numPicts; qq++) {
- short sizeIn;
- /* read size of pict, pict, and pict rect for each */
- toRead = sizeof(short);
- FSRead(readRefNum, &toRead, (Ptr)&sizeIn);
- *tempPictHand = NewHandle(sizeIn);
- HLock(*tempPictHand);
- toRead = sizeIn;
- FSRead(readRefNum, &toRead, (Ptr)(*(*tempPictHand)));
- HUnlock(*tempPictHand);
- *tempPictRects = NewHandle(sizeof(Rect));
-
- HLock(*tempPictRects);
- toRead = sizeof(Rect);
- FSRead(readRefNum, &toRead, (Ptr)(*(*tempPictRects)));
- HUnlock(*tempPictRects);
- tempPictRects += 1;
- tempPictHand += 1;
- }
- HUnlock((*newWinControl)->pictHandle);
- HUnlock((*newWinControl)->pictRects);
-
- }
- /* get any text */
- toRead = sizeof(short);
- FSRead(readRefNum, &toRead, (Ptr)&aShort);
- if (aShort) { /* if this has value (numerically, not ethically) then we need to make a TERecord */
- CharsHandle theText;
- Rect innerRect;
- theText = (CharsHandle)NewHandle(aShort);
- HLock((Handle)theText);
- toRead = aShort;
- FSRead(readRefNum, &toRead, (Ptr)*theText);
- /* read in the rect */
- toRead = sizeof(Rect);
- FSRead(readRefNum, &toRead, (Ptr)&(*newWinControl)->textBox);
- /* and create the TEControl */
- innerRect = (*newWinControl)->textBox;
- InsetRect(&innerRect, 3, 3);
- (*newWinControl)->boxHandle = TENew(&innerRect, &(*newWinControl)->textBox);
- TESetText((Ptr)*theText, aShort, (*newWinControl)->boxHandle);
- DisposeHandle((Handle)theText);
- }
- }
- FSClose(readRefNum);
- }
-
-
- #undef __FILES__
-